Wykorzystane biblioteki

library(knitr)
library(dplyr)
library(corrplot)
library(caret)
library(plotly)

Wczytywanie danych

df <- read.csv('data/sledzie.csv')

Exploratory data analysis

Struktura danych i podstawowe statystyki

Zbiór danych śledzie zawiera 52582 wierszy i 16 kolumn

dim(df)
## [1] 52582    16

Kolejne kolumny w zbiorze danych to:

  • X: numer porządkowy
  • length: długość złowionego śledzia [cm];
  • cfin1: dostępność planktonu [zagęszczenie Calanus finmarchicus gat. 1];
  • cfin2: dostępność planktonu [zagęszczenie Calanus finmarchicus gat. 2];
  • chel1: dostępność planktonu [zagęszczenie Calanus helgolandicus gat. 1];
  • chel2: dostępność planktonu [zagęszczenie Calanus helgolandicus gat. 2];
  • lcop1: dostępność planktonu [zagęszczenie widłonogów gat. 1];
  • lcop2: dostępność planktonu [zagęszczenie widłonogów gat. 2];
  • fbar: natężenie połowów w regionie [ułamek pozostawionego narybku];
  • recr: roczny narybek [liczba śledzi];
  • cumf: łączne roczne natężenie połowów w regionie [ułamek pozostawionego narybku];
  • totaln: łączna liczba ryb złowionych w ramach połowu [liczba śledzi];
  • sst: temperatura przy powierzchni wody [°C];
  • sal: poziom zasolenia wody [Knudsen ppt];
  • xmonth: miesiąc połowu [numer miesiąca];
  • nao: oscylacja północnoatlantycka [mb].

Wyświetlmy kilka pierwszych wierszy ze zbioru:

head(df)
##   X length   cfin1   cfin2   chel1    chel2   lcop1    lcop2  fbar   recr
## 1 0   23.0 0.02778 0.27785 2.46875        ? 2.54787 26.35881 0.356 482831
## 2 1   22.5 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831
## 3 2   25.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831
## 4 3   25.5 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831
## 5 4   24.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831
## 6 5   22.0 0.02778 0.27785 2.46875 21.43548 2.54787        ? 0.356 482831
##        cumf   totaln           sst      sal xmonth nao
## 1 0.3059879 267380.8 14.3069330186 35.51234      7 2.8
## 2 0.3059879 267380.8 14.3069330186 35.51234      7 2.8
## 3 0.3059879 267380.8 14.3069330186 35.51234      7 2.8
## 4 0.3059879 267380.8 14.3069330186 35.51234      7 2.8
## 5 0.3059879 267380.8 14.3069330186 35.51234      7 2.8
## 6 0.3059879 267380.8 14.3069330186 35.51234      7 2.8

Już w pierwszej obserwacji możemy znaleźć zastanawiającą wartość w kolumnie chel2 - znak zapytania. Najprawdopodobniej tak musiała być oznaczana wartość brakująca (??)

W zbiorze danych możemy zauważyć kilka kolumn oznaczonych jako dane kategoryczne (typ danych Factor). Co ciekawe kolummny te dotyczą dostępności planktonu oraz temperatury wody przy powierzchni, które wydawać by się mogło powinny być wyrażone poprzez liczby, jako dane ilościowe.

str(df)
## 'data.frame':    52582 obs. of  16 variables:
##  $ X     : int  0 1 2 3 4 5 6 7 8 9 ...
##  $ length: num  23 22.5 25 25.5 24 22 24 23.5 22.5 22.5 ...
##  $ cfin1 : Factor w/ 40 levels "?","0","0.01",..: 5 5 5 5 5 5 5 5 5 5 ...
##  $ cfin2 : Factor w/ 49 levels "?","0","0.01",..: 14 14 14 14 14 14 14 14 14 14 ...
##  $ chel1 : Factor w/ 49 levels "?","0","0.2287",..: 20 20 20 20 20 20 20 20 20 20 ...
##  $ chel2 : Factor w/ 52 levels "?","10.10963",..: 1 23 23 23 23 23 23 23 23 23 ...
##  $ lcop1 : Factor w/ 49 levels "?","0.30741",..: 20 20 20 20 20 20 20 20 20 20 ...
##  $ lcop2 : Factor w/ 52 levels "?","10.72889",..: 23 23 23 23 23 1 23 23 23 23 ...
##  $ fbar  : num  0.356 0.356 0.356 0.356 0.356 0.356 0.356 0.356 0.356 0.356 ...
##  $ recr  : int  482831 482831 482831 482831 482831 482831 482831 482831 482831 482831 ...
##  $ cumf  : num  0.306 0.306 0.306 0.306 0.306 ...
##  $ totaln: num  267381 267381 267381 267381 267381 ...
##  $ sst   : Factor w/ 52 levels "?","12.7690663857",..: 38 38 38 38 38 38 38 38 38 38 ...
##  $ sal   : num  35.5 35.5 35.5 35.5 35.5 ...
##  $ xmonth: int  7 7 7 7 7 7 7 7 7 7 ...
##  $ nao   : num  2.8 2.8 2.8 2.8 2.8 2.8 2.8 2.8 2.8 2.8 ...

ToDo: zamienić dane kategoryczne na ilościowe (?)

Obserowane długości śledzi są pomiędzy 19cm a 32.5cm. -> Szczegółowa analiza wartości atrybutów?

summary(df)
##        X             length         cfin1           cfin2      
##  Min.   :    0   Min.   :19.0   0      :14287   0.70118: 4374  
##  1st Qu.:13145   1st Qu.:24.0   0.02778: 2225   0      : 3806  
##  Median :26291   Median :25.5   1.02508: 2067   0.296  : 3706  
##  Mean   :26291   Mean   :25.3   1.21333: 1985   0.11736: 2106  
##  3rd Qu.:39436   3rd Qu.:26.5   0.33333: 1914   4.55825: 2007  
##  Max.   :52581   Max.   :32.5   0.11111: 1891   0.85684: 1665  
##                                 (Other):28213   (Other):34918  
##       chel1            chel2            lcop1            lcop2      
##  11.5    : 4787   5.67765 : 4365   23      : 4787   9.17171 : 4370  
##  2.46875 : 2241   21.67333: 3710   2.54787 : 2215   24.85867: 3709  
##  12.15192: 2109   39.56809: 2101   12.49588: 2105   41.65566: 2102  
##  6.42127 : 2062   26.81218: 2002   10.92857: 2059   45.70773: 1998  
##  19.15475: 2001   15.03   : 1941   21.23147: 1979   17.68   : 1959  
##  9.66667 : 1926   9.43208 : 1661   27.33333: 1916   10.72889: 1676  
##  (Other) :37456   (Other) :36802   (Other) :37521   (Other) :36768  
##       fbar             recr              cumf             totaln       
##  Min.   :0.0680   Min.   : 140515   Min.   :0.06833   Min.   : 144137  
##  1st Qu.:0.2270   1st Qu.: 360061   1st Qu.:0.14809   1st Qu.: 306068  
##  Median :0.3320   Median : 421391   Median :0.23191   Median : 539558  
##  Mean   :0.3304   Mean   : 520367   Mean   :0.22981   Mean   : 514973  
##  3rd Qu.:0.4560   3rd Qu.: 724151   3rd Qu.:0.29803   3rd Qu.: 730351  
##  Max.   :0.8490   Max.   :1565890   Max.   :0.39801   Max.   :1015595  
##                                                                        
##             sst             sal            xmonth            nao          
##  13.6315997001: 4359   Min.   :35.40   Min.   : 1.000   Min.   :-4.89000  
##  14.0693330238: 3700   1st Qu.:35.51   1st Qu.: 5.000   1st Qu.:-1.89000  
##  14.4415996823: 2080   Median :35.51   Median : 8.000   Median : 0.20000  
##  13.5598663683: 2010   Mean   :35.51   Mean   : 7.258   Mean   :-0.09236  
##  13.694933032 : 1950   3rd Qu.:35.52   3rd Qu.: 9.000   3rd Qu.: 1.63000  
##  13.861999695 : 1673   Max.   :35.61   Max.   :12.000   Max.   : 5.08000  
##  (Other)      :36810

Brakujące wartości

Brakujące wartości (oznaczone jako ‘?’) zostały zamienione na średnie wartości atrybutów. W ten sposób z niewygodnego typu kategorycznego można było przejść na typ numeryczny atrybutów.

change_na_to_mean <- function(column) {
  column <- as.numeric(as.character(column))
  column[is.na(column)] <- mean(column[!is.na(column)])
  column
}

data <- tbl_df(df)
data <- mutate_if(data, is.factor, change_na_to_mean)

Szczegółowa analiza wartości atrybutów

Poniżej został przedstawiony rozkład wartości dla wszystkich atrybutów.

summary(data)
##        X             length         cfin1             cfin2        
##  Min.   :    0   Min.   :19.0   Min.   : 0.0000   Min.   : 0.0000  
##  1st Qu.:13145   1st Qu.:24.0   1st Qu.: 0.0000   1st Qu.: 0.2778  
##  Median :26291   Median :25.5   Median : 0.1333   Median : 0.7012  
##  Mean   :26291   Mean   :25.3   Mean   : 0.4458   Mean   : 2.0248  
##  3rd Qu.:39436   3rd Qu.:26.5   3rd Qu.: 0.3603   3rd Qu.: 1.9973  
##  Max.   :52581   Max.   :32.5   Max.   :37.6667   Max.   :19.3958  
##      chel1            chel2            lcop1              lcop2       
##  Min.   : 0.000   Min.   : 5.238   Min.   :  0.3074   Min.   : 7.849  
##  1st Qu.: 2.469   1st Qu.:13.589   1st Qu.:  2.5479   1st Qu.:17.808  
##  Median : 6.083   Median :21.435   Median :  7.1229   Median :25.338  
##  Mean   :10.006   Mean   :21.221   Mean   : 12.8108   Mean   :28.419  
##  3rd Qu.:11.500   3rd Qu.:27.193   3rd Qu.: 21.2315   3rd Qu.:37.232  
##  Max.   :75.000   Max.   :57.706   Max.   :115.5833   Max.   :68.736  
##       fbar             recr              cumf             totaln       
##  Min.   :0.0680   Min.   : 140515   Min.   :0.06833   Min.   : 144137  
##  1st Qu.:0.2270   1st Qu.: 360061   1st Qu.:0.14809   1st Qu.: 306068  
##  Median :0.3320   Median : 421391   Median :0.23191   Median : 539558  
##  Mean   :0.3304   Mean   : 520367   Mean   :0.22981   Mean   : 514973  
##  3rd Qu.:0.4560   3rd Qu.: 724151   3rd Qu.:0.29803   3rd Qu.: 730351  
##  Max.   :0.8490   Max.   :1565890   Max.   :0.39801   Max.   :1015595  
##       sst             sal            xmonth            nao          
##  Min.   :12.77   Min.   :35.40   Min.   : 1.000   Min.   :-4.89000  
##  1st Qu.:13.63   1st Qu.:35.51   1st Qu.: 5.000   1st Qu.:-1.89000  
##  Median :13.86   Median :35.51   Median : 8.000   Median : 0.20000  
##  Mean   :13.87   Mean   :35.51   Mean   : 7.258   Mean   :-0.09236  
##  3rd Qu.:14.16   3rd Qu.:35.52   3rd Qu.: 9.000   3rd Qu.: 1.63000  
##  Max.   :14.73   Max.   :35.61   Max.   :12.000   Max.   : 5.08000

Rozkład wartości dla poszczególnych atrybutów najłatwiej będzie zobrazować za pomocą wykresów pudełkowych. Dla lepszej czytelności rozkładu atrybutów opisujących dostępność planktonu dodano także drugi wykres niezawierający obserwacji odstających.

boxplot(data$length, horizontal = TRUE, main = "Długość śledzia", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data[, 3:8], col = rainbow(6, v = 0.5, start = 0, end = 1), main = "Dostępność planktonu")

boxplot(data[, 3:8], col = rainbow(6, v = 0.5, start = 0, end = 1), main = "Dostępność planktonu", outline = FALSE)

boxplot(data[, 3:4], col = rainbow(2, v = 0.5, start = 0, end = 0.2), main = "Zagęszczenie Calanus finmarchicus")

boxplot(data[, 3:4], col = rainbow(2, v = 0.5, start = 0, end = 0.2), main = "Zagęszczenie Calanus finmarchicus", outline = FALSE)

boxplot(data[, 5:6], col = rainbow(2, v = 0.5, start = 0.4, end = 0.6), main = "Zagęszczenie Calanus helgolandicus")

boxplot(data[, 5:6], col = rainbow(2, v = 0.5, start = 0.4, end = 0.6), main = "Zagęszczenie Calanus helgolandicus", outline = FALSE)

boxplot(data[, 7:8], col = rainbow(2, v = 0.5, start = 0.8, end = 1), main = "Zagęszczenie widłonogów")

boxplot(data[, 7:8], col = rainbow(2, v = 0.5, start = 0.8, end = 1), main = "Zagęszczenie widłonogów", outline = FALSE)

boxplot(data$length, horizontal = TRUE, main = "Natężenie połowów w regionie", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data$fbar, horizontal = TRUE, main = "Roczny narybek", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data$recr, horizontal = TRUE, main = "Łączne roczne natężenie połowów w regionie", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data$cumf, horizontal = TRUE, main = "Łączna liczba ryb złowionych w ramach połowu", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data$totaln, horizontal = TRUE, main = "Temperatura przy powierzchni wody", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data$sst, horizontal = TRUE, main = "Poziom zasolenia wody", col = hsv(h = 240/360, s = 0.5, v = 0.5))

boxplot(data$nao, horizontal = TRUE, main = "Oscylacja północnoatlantycka", col = hsv(h = 240/360, s = 0.5, v = 0.5))

Korelacja

Analizę korelacji przeprowadzono w oparciu o macierz korelacji pomiędzy atrybutami.

data %>% select(-X) %>% as.matrix() %>% cor() %>% corrplot(method = "circle")

Z macierzy korelacji można wywnioskować, że długość śledzia jest zależna od temperatury przy powierzchni wody - możemy dostrzec silną negatywną korelację. Widać również, że długość śledzia jest zależna od oscylacji północnoatlantyckiej - tutaj także korelacja jest negatywna.

Prezentacja zmiany rozmiaru śledzi w czasie

Poniższy wykres przedstawia zmianę rozmiaru śledzi w czasie. Został zwizualizowany na podstawie 20% danych z uwagi na to, żeby interakcja z wykresem była płynna.

partition <- createDataPartition(y = data$length, p = 0.2, list = FALSE)
data_partition <- data[partition, ]
p <- ggplot(data_partition, aes(X, length)) + geom_point() + geom_smooth() + theme_bw()
ggplotly(p)